from pyglet.gl import *
import pyglet
import windoh


class OpenGLStyle(windoh.Style):
    opengl_initial = {
        'Control': {
            'background_color': None,
            'border_width': 1,
            'border_color': (0.0, 0.0, 0.0),
            'border_style': None,
        },
        'Label': {
            'font_size': 10,
            'font_face': 'Sans',
            'font_color': (1.0, 1.0, 1.0),
        },
        'Button': {
            'border_color': (1.0, 1.0, 1.0),
            'border_style': 'single',
            'background_color': (0.5, 0.5, 0.5),
        },
        'Frame': { 
            'border_color': (1.0, 1.0, 1.0),
            'border_style': 'single',
            'background_color': (0.5, 0.5, 0.5),
            'title_font_size': 10,
            'title_font_face': 'Sans',
            'title_font_color': (1.0, 1.0, 1.0),
            'title_height': 20,
        },
        'Window': {
            'title_background_color': (0.4, 0.4, 0.4),
            'resize_handle_size': 10,
        },
    }

    def __init__(self, owner=None, initial=None):
        style = self.opengl_initial.copy()
        if initial:
            style.update(initial)
        windoh.Style.__init__(self, owner=owner, initial=style)


def rect(x, y, w, h, mode=GL_QUADS):
    glBegin(mode)
    #glTexCoord2f (0.0, 1.0);
    glVertex2i(x, y)
    #glTexCoord2f(1.0, 1.0);
    glVertex2i(x+w, y)
    #glTexCoord2f(1.0, 0.0);
    glVertex2i(x+w, y+h)
    #glTexCoord2f(0.0, 0.0);
    glVertex2i(x, y+h)
    glEnd ()


class ControlRenderer(object):

    def __call__(self, control, style, context):
        w = control.style['width']
        h = control.style['height']
        self.redraw(control, style, context, w, h)
        
    def redraw(self, control, style, context, w, h):
        self.draw_background(control, style, context, w, h)
        self.draw_border(control, style, context, w, h)

    def draw_background(self, control, style, context, w, h):
        if style['background_color']:
            glColor3f(*style['background_color'])
            rect(0, 0, w, h)

    def draw_border(self, control, style, context, w, h):
        if style['border_style'] and style['border_width'] > 0 and style['border_color']:
            glLineWidth(style['border_width'])
            glColor3f(*style['border_color'])
            rect(0, 0, w, h, GL_LINE_LOOP)
                

def draw_text(style, ctx, w, h, text, prefix=''):
    if (style[prefix+'font_color'] and 
        style[prefix+'font_face'] and 
        style[prefix+'font_size']):
        ctx.set_source_rgb(*style[prefix+'font_color'])
        ctx.select_font_face(style[prefix+'font_face'], False, False)
        ctx.set_font_size(style[prefix+'font_size'])
        extents = ctx.text_extents(text)
        #return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing,
        #     extents.width, extents.height, extents.x_advance,
        #     extents.y_advance);

        x = (w/2)-(extents[2]/2 + extents[0])
        y = (h/2)-(extents[3]/2 + extents[1])

        ctx.move_to(x, y)
        ctx.show_text(text)

def configure_label(label, style, prefix=''):
    print style
    label.font_name = style[prefix+'font_face']
    label.font_size = style[prefix+'font_size']
    label.font_color = style[prefix+'font_color']


class LabelRenderer(ControlRenderer):
    def redraw(self, control, style, context, w, h):
        ControlRenderer.redraw(self, control, style, context, w, h)
        try:
            label = context['label']
        except KeyError:
            label = context['label'] = pyglet.text.Label(control.label, 
                halign="center", valign="center",
            )
            configure_label(label, style)
        label.x = w / 2
        label.y = h / 2
        label.draw()


class FrameRenderer(ControlRenderer):
    def redraw(self, control, style, context, w, h):
        ControlRenderer.draw_background(self, control, style, context, w, h)

        try:
            label = context['label']
        except KeyError:
            label = context['label'] = pyglet.text.Label(control.label, 
                halign="center", valign="center",
            )
            configure_label(label, style, 'title_')

        self.draw_title(control, style, context, w, h, label)

        ControlRenderer.draw_border(self, control.label, style, context, w, h)

    def draw_title(self, control, style, context, w, h, label):
        label.x = w / 2
        label.y = style['height'] - 2 - (style['title_height'] / 2)
        label.draw()

        
class WindowRenderer(FrameRenderer):
    def draw_title(self, control, style, context, w, h, label):
        glColor3f(*style['title_background_color'])
        rect(0, style['height'] - style['title_height'], w, style['title_height'])
        FrameRenderer.draw_title(self, control, style, context, w, h, label)
        

class OpenGLRenderer(windoh.Renderer):
    def __init__(self, style, initial=None):
        opengl_renderers = {
            'Control': ControlRenderer(),
            'Label': LabelRenderer(),
            'Frame': FrameRenderer(),
            'Window': WindowRenderer(),
        }
        if initial:
            opengl_renderers.update(initial)
        windoh.Renderer.__init__(self, style, opengl_renderers)


